package com.example.zhu29.bledemo.util;

import android.annotation.SuppressLint;
import android.text.TextUtils;
import android.util.Log;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import static com.example.zhu29.bledemo.util.ZConstTool.DAY;
import static com.example.zhu29.bledemo.util.ZConstTool.HOUR;
import static com.example.zhu29.bledemo.util.ZConstTool.MIN;
import static com.example.zhu29.bledemo.util.ZConstTool.MSEC;
import static com.example.zhu29.bledemo.util.ZConstTool.SEC;

/**
 * Created by zhudewei on 2016/1/24.
 * Time related tools
 */
public class ZTimeTool {


    /**
     * <p>The format description of the tool class is often used in the tool class. This is mainly a date operation class, so the log format mainly uses the definition format of SimpleDateFormat..</p>
     *The meaning of the format is as follows: Date and time mode<br>
     * <p>The date and time format is specified by the date and time pattern string. In date and time pattern strings, the unquoted letters 'A' through 'Z' and 'a' through 'z'
     * are interpreted as pattern letters to represent date or time string elements. Text can be enclosed in single quotes (') to avoid interpretation. "''" means single quotes.
     * All other characters are not interpreted; they are simply copied to the output string when formatting, or matched to the input string during parsing.
     * </p>
     * The following pattern letters are defined (all other characters 'A' through 'Z' and 'a' through 'z' are reserved): <br>
     * <table border="1" cellspacing="1" cellpadding="1" summary="Chart shows pattern letters, date/time component,
     * presentation, and examples.">
     * <tr>
     * <th align="left">letter</th>
     * <th align="left">Date or time element</th>
     * <th align="left">Express</th>
     * <th align="left">Example</th>
     * </tr>
     * <tr>
     * <td><code>G</code></td>
     * <td>Era Signifier</td>
     * <td>Text</td>
     * <td><code>AD</code></td>
     * </tr>
     * <tr>
     * <td><code>y</code> </td>
     * <td>year </td>
     * <td>Year </td>
     * <td><code>1996</code>; <code>96</code> </td>
     * </tr>
     * <tr>
     * <td><code>M</code> </td>
     * <td>Month of the year </td>
     * <td>Month </td>
     * <td><code>July</code>; <code>Jul</code>; <code>07</code> </td>
     * </tr>
     * <tr>
     * <td><code>w</code> </td>
     * <td>Number of weeks in the year </td>
     * <td>Number </td>
     * <td><code>27</code> </td>
     * </tr>
     * <tr>
     * <td><code>W</code> </td>
     * <td>Number of weeks in the month </td>
     * <td>Number </td>
     * <td><code>2</code> </td>
     * </tr>
     * <tr>
     * <td><code>D</code> </td>
     * <td>Number of days in the year </td>
     * <td>Number </td>
     * <td><code>189</code> </td>
     * </tr>
     * <tr>
     * <td><code>d</code> </td>
     * <td>Number of days in the month </td>
     * <td>Number </td>
     * <td><code>10</code> </td>
     * </tr>
     * <tr>
     * <td><code>F</code> </td>
     * <td>Week of the month </td>
     * <td>Number </td>
     * <td><code>2</code> </td>
     * </tr>
     * <tr>
     * <td><code>E</code> </td>
     * <td>Number of days in the week </td>
     * <td>Text </td>
     * <td><code>Tuesday</code>; <code>Tue</code> </td>
     * </tr>
     * <tr>
     * <td><code>a</code> </td>
     * <td>Am/pm mark </td>
     * <td>Text </td>
     * <td><code>PM</code> </td>
     * </tr>
     * <tr>
     * <td><code>H</code> </td>
     * <td>Hours of the day（0-23） </td>
     * <td>Number </td>
     * <td><code>0</code> </td>
     * </tr>
     * <tr>
     * <td><code>k</code> </td>
     * <td>Hours of the day（1-24） </td>
     * <td>Number </td>
     * <td><code>24</code> </td>
     * </tr>
     * <tr>
     * <td><code>K</code> </td>
     * <td>Hours in am/pm (0-11) </td>
     * <td>Number </td>
     * <td><code>0</code> </td>
     * </tr>
     * <tr>
     * <td><code>h</code> </td>
     * <td>Hours in am/pm (1-12) </td>
     * <td>Number </td>
     * <td><code>12</code> </td>
     * </tr>
     * <tr>
     * <td><code>m</code> </td>
     * <td>Minutes in hours </td>
     * <td>Number </td>
     * <td><code>30</code> </td>
     * </tr>
     * <tr>
     * <td><code>s</code> </td>
     * <td>The number of seconds in minutes </td>
     * <td>Number </td>
     * <td><code>55</code> </td>
     * </tr>
     * <tr>
     * <td><code>S</code> </td>
     * <td>Number of milliseconds </td>
     * <td>Number </td>
     * <td><code>978</code> </td>
     * </tr>
     * <tr>
     * <td><code>z</code> </td>
     * <td>Time zone </td>
     * <td>General time zone </td>
     * <td><code>Pacific Standard Time</code>; <code>PST</code>; <code>GMT-08:00</code> </td>
     * </tr>
     * <tr>
     * <td><code>Z</code> </td>
     * <td>Time zone </td>
     * <td>RFC 822 time zone </td>
     * <td><code>-0800</code> </td>
     * </tr>
     * </table>
     * <pre>
     *                          HH:mm    15:44
     *                         h:mm a    3:44 in the afternoon
     *                        HH:mm z    15:44 CST
     *                        HH:mm Z    15:44 +0800
     *                     HH:mm zzzz    15:44 China Standard Time
     *                       HH:mm:ss    15:44:40
     *                     yyyy-MM-dd    2016-08-12
     *               yyyy-MM-dd HH:mm    2016-08-12 15:44
     *            yyyy-MM-dd HH:mm:ss    2016-08-12 15:44:40
     *       yyyy-MM-dd HH:mm:ss zzzz    2016-08-12 15:44:40 China Standard Time
     *  EEEE yyyy-MM-dd HH:mm:ss zzzz    Friday 2016-08-12 15:44:40 China Standard Time
     *       yyyy-MM-dd HH:mm:ss.SSSZ    2016-08-12 15:44:40.461+0800
     *     yyyy-MM-dd'T'HH:mm:ss.SSSZ    2016-08-12T15:44:40.461+0800
     *   yyyy.MM.dd G 'at' HH:mm:ss z    2016.08.12 A.D. at 15:44:40 CST
     *                         K:mm a    3:44 in the afternoon
     *               EEE, MMM d, ''yy    Friday, August 12, '16
     *          hh 'o''clock' a, zzzz    03 o'clock in the afternoon, China Standard Time
     *   yyyyy.MMMMM.dd GGG hh:mm aaa    02016.August.12 A.D. 03:44 in the afternoon
     *     EEE, d MMM yyyy HH:mm:ss Z    Friday, 12 August 2016 15:44:40 +0800
     *                  yyMMddHHmmssZ    160812154440+0800
     *     yyyy-MM-dd'T'HH:mm:ss.SSSZ    2016-08-12T15:44:40.461+0800
     * EEEE 'DATE('yyyy-MM-dd')' 'TIME('HH:mm:ss')' zzzz    Friday DATE(2016-08-12) TIME(15:44:40) China Standard Time
     * </pre>
     */
    public static final SimpleDateFormat DEFAULT_SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
    private static SimpleDateFormat dfYMD = new SimpleDateFormat("yyyy-MM-dd");


    /**
     * Convert timestamp to time string
     * <p>Format is yyyy-MM-dd HH:mm:ss</p>
     *
     * @param milliseconds Millisecond timestamp
     * @return Time string
     */
    public static String milliseconds2String(long milliseconds) {
        return milliseconds2String(milliseconds, DEFAULT_SDF);
    }

    /**
     * Convert timestamp to time string
     * <p>Format is user-defined</p>
     *
     * @param milliseconds Millisecond timestamp
     * @param format       Time format
     * @return Time string
     */
    public static String milliseconds2String(long milliseconds, SimpleDateFormat format) {
        return format.format(new Date(milliseconds));
    }

    /**
     * Convert timestamp to time string
     * <p>Format is user-defined</p>
     *
     * @param milliseconds Millisecond timestamp
     * @param format       Time format
     * @return Time string
     */
    public static String milliseconds2String(long milliseconds, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return sdf.format(new Date(milliseconds));
    }

    /**
     * Convert time string to timestamp
     * <p>Format is yyyy-MM-dd HH:mm:ss</p>
     *
     * @param time Time string
     * @return Millisecond timestamp
     */
    public static long string2Milliseconds(String time) {
        return string2Milliseconds(time, DEFAULT_SDF);
    }

    /**
     * Convert time string to timestamp
     * <p>Format is user-defined</p>
     *
     * @param time   Time string
     * @param format Time format
     * @return Millisecond timestamp
     */
    public static long string2Milliseconds(String time, SimpleDateFormat format) {
        try {
            return format.parse(time).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return -1;
    }

    /**
     * Convert time string to Date type
     * <p>Format is yyyy-MM-dd HH:mm:ss</p>
     *
     * @param time Time string
     * @return Date type
     */
    public static Date string2Date(String time) {
        return string2Date(time, DEFAULT_SDF);
    }

    /**
     * Convert time string to Date type
     * <p>Format is user-defined</p>
     *
     * @param time   Time string
     * @param format Time format
     * @return Date type
     */
    public static Date string2Date(String time, SimpleDateFormat format) {
        return new Date(string2Milliseconds(time, format));
    }

    /**
     * Convert Date type to time string
     * <p>Format is yyyy-MM-dd HH:mm:ss</p>
     *
     * @param time Date type time
     * @return Time string
     */
    public static String date2String(Date time) {
        return date2String(time, DEFAULT_SDF);
    }

    /**
     * Convert Date type to time string
     * <p>Format is user-defined</p>
     *
     * @param time   Date type time
     * @param format Time format
     * @return Time string
     */
    public static String date2String(Date time, SimpleDateFormat format) {
        return format.format(time);
    }

    public static String stringFormat(String date, SimpleDateFormat from, SimpleDateFormat to) {
        try {
            return to.format(from.parse(date));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return "";
    }

    public static String stringFormat(String date, String from, String to) {
        try {
            return new SimpleDateFormat(to).format(new SimpleDateFormat(from).parse(date));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * Convert Date type to timestamp
     *
     * @param time Date type time
     * @return Millisecond timestamp
     */
    public static long date2Milliseconds(Date time) {
        return time.getTime();
    }

    /**
     * Convert timestamp to Date type
     *
     * @param milliseconds Millisecond timestamp
     * @return Date type time
     */
    public static Date milliseconds2Date(long milliseconds) {
        return new Date(milliseconds);
    }

    /**
     * Millisecond timestamp unit conversion (unit: unit)
     *
     * @param milliseconds Millisecond timestamp
     * @param unit         <ul>
     *                     <li>{@link ZConstTool.TimeUnit#MSEC}: millisecond</li>
     *                     <li>{@link ZConstTool.TimeUnit#SEC }: second</li>
     *                     <li>{@link ZConstTool.TimeUnit#MIN }: Minute</li>
     *                     <li>{@link ZConstTool.TimeUnit#HOUR}: hour</li>
     *                     <li>{@link ZConstTool.TimeUnit#DAY }: day</li>
     *                     </ul>
     * @return Unit timestamp
     */
    private static long milliseconds2Unit(long milliseconds, ZConstTool.TimeUnit unit) {
        switch (unit) {
            case MSEC:
                return milliseconds / MSEC;
            case SEC:
                return milliseconds / SEC;
            case MIN:
                return milliseconds / MIN;
            case HOUR:
                return milliseconds / HOUR;
            case DAY:
                return milliseconds / DAY;
        }
        return -1;
    }

    /**
     *Get two time differences (unit: unit)
     * <p>time1和time2 The format is yyyy-MM-dd HH:mm:ss</p>
     *
     * @param time0 Time string 1
     * @param time1 Time string 2
     * @param unit  <ul>
     *              <li>{@link ZConstTool.TimeUnit#MSEC}: millisecond</li>
     *              <li>{@link ZConstTool.TimeUnit#SEC }: second</li>
     *              <li>{@link ZConstTool.TimeUnit#MIN }: Minute</li>
     *              <li>{@link ZConstTool.TimeUnit#HOUR}: hour</li>
     *              <li>{@link ZConstTool.TimeUnit#DAY }: day</li>
     *              </ul>
     * @return Unit timestamp
     */
    public static long getIntervalTime(String time0, String time1, ZConstTool.TimeUnit unit) {
        return getIntervalTime(time0, time1, unit, DEFAULT_SDF);
    }

    /**
           * Get two time differences (unit: unit)
           * <p> Both time1 and time2 formats are format</p>
           *
           * @param time0 time string 1
           * @param time1 time string 2
           * @param unit <ul>
           * <li>{@link ZConstTool.TimeUnit#MSEC}: milliseconds</li>
           * <li>{@link ZConstTool.TimeUnit#SEC }: seconds</li>
           * <li>{@link ZConstTool.TimeUnit#MIN }: points</li>
           * <li>{@link ZConstTool.TimeUnit#HOUR}: Hours</li>
           * <li>{@link ZConstTool.TimeUnit#DAY }: Days</li>
           * </ul>
           * @param format time format
           * @return unit timestamp
           */
    public static long getIntervalTime(String time0, String time1, ZConstTool.TimeUnit unit, SimpleDateFormat format) {
        return Math.abs(milliseconds2Unit(string2Milliseconds(time0, format)
                - string2Milliseconds(time1, format), unit));
    }

    /**
           * Get two time differences (unit: unit)
           * <p>time1 and time2 are both of type Date</p>
           *
           * @param time0 Date type time 1
           * @param time1 Date type time 2
           * @param unit <ul>
           * <li>{@link ZConstTool.TimeUnit#MSEC}: milliseconds</li>
           * <li>{@link ZConstTool.TimeUnit#SEC }: seconds</li>
           * <li>{@link ZConstTool.TimeUnit#MIN }: points</li>
           * <li>{@link ZConstTool.TimeUnit#HOUR}: Hours</li>
           * <li>{@link ZConstTool.TimeUnit#DAY }: Days</li>
           * </ul>
           * @return unit timestamp
           */
    public static long getIntervalTime(Date time0, Date time1, ZConstTool.TimeUnit unit) {
        return Math.abs(milliseconds2Unit(date2Milliseconds(time1)
                - date2Milliseconds(time0), unit));
    }

    /**
           * Get current time
           *
           * @return millisecond timestamp
           */
    public static long getCurTimeMills() {
        return System.currentTimeMillis();
    }

    /**
           * Get current time
           * <p>The format is yyyy-MM-dd HH:mm:ss</p>
           *
           * @return time string
           */
    public static String getCurTimeString() {
        return date2String(new Date());
    }

    /**
           * Get current time
           * <p>Format is user-defined</p>
           *
           * @param format time format
           * @return time string
           */
    public static String getCurTimeString(SimpleDateFormat format) {
        return date2String(new Date(), format);
    }

    /**
           * Get current time
           * <p>Date type</p>
           *
           * @return Date type time
           */
    public static Date getCurTimeDate() {
        return new Date();
    }

    /**
           * Get the difference from the current time (unit: unit)
           * <p>time format is yyyy-MM-dd HH:mm:ss</p>
           *
           * @param time time string
           * @param unit <ul>
           * <li>{@link ZConstTool.TimeUnit#MSEC}: milliseconds</li>
           * <li>{@link ZConstTool.TimeUnit#SEC }: seconds</li>
           * <li>{@link ZConstTool.TimeUnit#MIN }: points</li>
           * <li>{@link ZConstTool.TimeUnit#HOUR}: Hours</li>
           * <li>{@link ZConstTool.TimeUnit#DAY }: Days</li>
           * </ul>
           * @return unit timestamp
           */
    public static long getIntervalByNow(String time, ZConstTool.TimeUnit unit) {
        return getIntervalByNow(time, unit, DEFAULT_SDF);
    }

    /**
           * Get the difference from the current time (unit: unit)
           * <p>time format is format</p>
           *
           * @param time time string
           * @param unit <ul>
           * <li>{@link ZConstTool.TimeUnit#MSEC}: milliseconds</li>
           * <li>{@link ZConstTool.TimeUnit#SEC }: seconds</li>
           * <li>{@link ZConstTool.TimeUnit#MIN }: points</li>
           * <li>{@link ZConstTool.TimeUnit#HOUR}: Hours</li>
           * <li>{@link ZConstTool.TimeUnit#DAY }: Days</li>
           * </ul>
           * @param format time format
           * @return unit timestamp
           */
    public static long getIntervalByNow(String time, ZConstTool.TimeUnit unit, SimpleDateFormat format) {
        return getIntervalTime(getCurTimeString(), time, unit, format);
    }

    /**
           * Get the difference from the current time (unit: unit)
           * <p>time is Date type</p>
           *
           * @param time Date type time
           * @param unit <ul>
           * <li>{@link ZConstTool.TimeUnit#MSEC}: milliseconds</li>
           * <li>{@link ZConstTool.TimeUnit#SEC }: seconds</li>
           * <li>{@link ZConstTool.TimeUnit#MIN }: points</li>
           * <li>{@link ZConstTool.TimeUnit#HOUR}: Hours</li>
           * <li>{@link ZConstTool.TimeUnit#DAY }: Days</li>
           * </ul>
           * @return unit timestamp
           */
    public static long getIntervalByNow(Date time, ZConstTool.TimeUnit unit) {
        return getIntervalTime(getCurTimeDate(), time, unit);
    }

    /**
           * Judging the leap year
           *
           * @param year year
           * @return {@code true}: leap year<br>{@code false}: average year
           */
    public static boolean isLeapYear(int year) {
        return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
    }

    /**
           * Convert date to date in format format
           *
           * @param format format
           * @param date Date
           * @return
           */
    public static String simpleDateFormat(String format, Date date) {
        if (TextUtils.isEmpty(format)) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        String content = sdf.format(date);
        return content;
    }

    //--------------------------------------------Convert a string to a timestamp-----------------------------------

    /**
     * Convert dates of the specified format to timestamps
     *
     * @param mDate
     * @return
     */
    public static String Date2Timestamp(Date mDate) {
        return String.valueOf(mDate.getTime()).substring(0, 10);
    }

    /**
           * Convert date string to DATE according to the specified format
           * return null when the conversion fails;
           *
           * @param format
           * @param datess
           * @return
           */
    public static Date string2Date(String format, String datess) {
        SimpleDateFormat sdr = new SimpleDateFormat(format);
        sdr.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        Date date = null;
        try {
            date = sdr.parse(datess);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
           * Convert yyyy year MM month dd day to timestamp
           *
           * @param format
           * @param datess
           * @return
           */
    public static String string2Timestamp(String format, String datess) {
        Date date = string2Date(format, datess);
        return Date2Timestamp(date);
    }
    //===========================================Convert a string to a timestamp====================================

    /**
           * Get current date and time / Get today's date
           * str yyyyMMddhhMMss
           *
           * @return
           */
    @SuppressLint("SimpleDateFormat")
    public static String getCurrentDateTime(String format) {
        return simpleDateFormat(format, new Date());
    }

    /**
           * Timestamp is converted to the date in the specified format
           * If format is empty, the default format is
           *
           * @param times timestamp
           * @param format date format yyyy-MM-dd HH:mm:ss
           * @return
           */
    @SuppressLint("SimpleDateFormat")
    public static String getDate(String times, String format) {
        return simpleDateFormat(format, new Date(stringToInt(times) * 1000L));
    }
    /**
           * The string is converted to an integer, and the conversion will return 0;
           *
           * @param str string
           * @return
           */
    public static int stringToInt(String str) {
        if (TextUtils.isEmpty(str)) {
            return 0;
        } else {
            try {
                return Integer.parseInt(str);
            } catch (NumberFormatException e) {
                return 0;
            }
        }
    }

    /**
           * Get yesterday's date
           *
           * @param format date format yyyy-MM-dd HH:mm:ss
           * @return
           */
    public static String getYestoryDate(String format) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -1);
        return simpleDateFormat(format, calendar.getTime());
    }

    /**
           * Video time is converted to "mm:ss"
           *
           * @param milliseconds
           * @return
           */
    public static String formatTime(long milliseconds) {
        String format = "mm:ss";
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        String video_time = sdf.format(milliseconds);
        return video_time;
    }

    /**
           * "mm:ss" converted to video time
           *
           * @param time
           * @return
           */
    public static long formatSeconds(String time) {
        String format = "mm:ss";
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        Date date;
        long times = 0;
        try {
            date = sdf.parse(time);
            long l = date.getTime();
            times = l;
            Log.d("Timestamp", times + "");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return times;
    }

    /**
           * According to the year month, get the corresponding month, the number of days
           */
    public static int getDaysByYearMonth(int year, int month) {
        Calendar a = Calendar.getInstance();
        a.set(Calendar.YEAR, year);
        a.set(Calendar.MONTH, month - 1);
        a.set(Calendar.DATE, 1);
        a.roll(Calendar.DATE, -1);
        int maxDate = a.get(Calendar.DATE);
        return maxDate;
    }

    /**
           * Determine the current date is the day of the week
           *
           * @param strDate Fix the time to judge
           * @return dayForWeek
           * @Exception An exception occurred <br>
           */
    public static int stringForWeek(String strDate) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(format.parse(strDate));
        if (c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            return 7;
        } else {
            return c.get(Calendar.DAY_OF_WEEK) - 1;
        }
    }

    /**
           * Determine the current date is the day of the week
           *
           * @param strDate Fix the time to judge
           * @return dayForWeek
           * @Exception An exception occurred <br>
           */
    public static int stringForWeek(String strDate, SimpleDateFormat simpleDateFormat) throws Exception {
        Calendar c = Calendar.getInstance();
        c.setTime(simpleDateFormat.parse(strDate));
        if (c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            return 7;
        } else {
            return c.get(Calendar.DAY_OF_WEEK) - 1;
        }
    }

    public static String getWeek(String strDate) {
        String week = null;
        try {
            int index = stringForWeek(strDate);
            switch (index) {
                case 1:
                    week = " Monday ";
                    break;
                case 2:
                    week = " Tuesday ";
                    break;
                case 3:
                    week = " Wednesday ";
                    break;
                case 4:
                    week = " Thursday ";
                    break;
                case 5:
                    week = " Friday ";
                    break;
                case 6:
                    week = " Saturday ";
                    break;
                case 7:
                    week = " Sunday ";
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return week;
    }

    public static String getFirstDayWeek() {

        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_WEEK, (-1) * c.get(Calendar.DAY_OF_WEEK) + 2);
        return dfYMD.format(c.getTime());
    }

    public static String getLastDayByWeek() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_WEEK, 7 - c.get(Calendar.DAY_OF_WEEK) + 1);
        return dfYMD.format(c.getTime());
    }

    public static String getFirstDayByMonth() {
        //Get the first day of the previous month
        Calendar cal_1 = Calendar.getInstance();//Get the current date
        cal_1.add(Calendar.MONTH, 0);
        cal_1.set(Calendar.DAY_OF_MONTH, 1);//Set to number 1, the current date is the first day of the month
        return dfYMD.format(cal_1.getTime());
    }

    public static String getLastDayByMonth() {
        Calendar ca = Calendar.getInstance();
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        return dfYMD.format(ca.getTime());
    }

    public static String getYearByAge(int age) {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.YEAR, -age);
        return dfYMD.format(c.getTime());
    }

    public static boolean compare(String time1, String time2) {
        //If you want to compare dates, write "yyyy-MM-dd".
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //Convert time in string form to time in Date type
        Date a = null;
        try {
            a = sdf.parse(time1);
            Date b = sdf.parse(time2);
            //A method of the Date class, if a returns true before b, otherwise returns false
            return a.before(b);
        } catch (ParseException e) {
            e.printStackTrace();
            return false;
        }
        /*
         * If you don't like to use the above-mentioned too rogue method, you can also convert Date to milliseconds.
        if(a.getTime()-b.getTime()<0)
            return true;
        else
            return false;
        */
    }

    public static String getBefore3Day() {
        Calendar ca = Calendar.getInstance();
        ca.set(Calendar.DAY_OF_YEAR, ca.get(Calendar.DAY_OF_YEAR) - 2);
        return dfYMD.format(ca.getTime());
    }

    public static String getBefore7Day() {
        Calendar ca = Calendar.getInstance();
        ca.set(Calendar.DAY_OF_YEAR, ca.get(Calendar.DAY_OF_YEAR) - 6);
        return dfYMD.format(ca.getTime());
    }

    public static boolean betweenTime(String currentHm, String startTime, String endTime) {
        String[] arrStart = startTime.split(":");
        String[] arrEnd = endTime.split(":");
        String[] arrCurrentHm = currentHm.split(":");

        int startH = Integer.parseInt(arrStart[0]);
        int startM = Integer.parseInt(arrStart[1]);
        long start = startH * 60 + startM;

        int endH = Integer.parseInt(arrEnd[0]);
        int endM = Integer.parseInt(arrEnd[1]);
        long end = endH * 60 + endM;

        int currentH = Integer.parseInt(arrCurrentHm[0]);
        int currentM = Integer.parseInt(arrCurrentHm[1]);
        long current = currentH * 60 + currentM;

        if (end < start) {
            if (currentH >= 0 && currentH < 10) {
                return current <= start && current <= end;
            }
            return current >= start && current >= end;
        }
        return (current >= start && current <= end);
    }
}